macro_rules! create_function {
    ($func_name: ident) => {
        fn $func_name() {
            println!("function {:?} is called", stringify!($func_name))
        }
    };
}

pub fn test_create_function() {
    create_function!(foo);
    foo();
}

fn foo1(x: i32) -> i32 {
    x * x
}
macro_rules! foo1 {
    ($x: ident) => {println!("{:?}", $x);};
}
pub fn test_foo1() {
    let a = 5;
    foo1!(a);
    println!("{}", foo1(a));
}


//当前宏支持以下几种指示符：
//
//ident: 标识符，用来表示函数或变量名
//expr: 表达式
//block: 代码块，用花括号包起来的多个语句
//pat: 模式，普通模式匹配（非宏本身的模式）中的模式，例如 Some(t), (3, 'a', _)
//path: 路径，注意这里不是操作系统中的文件路径，而是用双冒号分隔的限定名(qualified name)，如 std::cmp::PartialOrd
//tt: 单个语法树
//ty: 类型，语义层面的类型，如 i32, char
//item: 条目，
//meta: 元条目
//stmt: 单条语句，如 let a = 42;
macro_rules! vector {
    ($($x: expr), *) => {
        {
            let mut temp_vec = Vec::new();
            //重复的模式需要用括号括起来，外面再加上 $，例如 $(...)*, $(...)+
            $(temp_vec.push($x);)*
            temp_vec
        }
    };
}
pub fn test_vector() {
    let a = vector![1, 2, 3, 4, 5];
    println!("{:?}", a);
}
//递归的宏。
use ::std::cmp::min;
macro_rules! find_min {
    ($x: expr) => {$x};
    ($x: expr, $($y: expr), +) => (
        min($x, find_min!($($y), +))
    )
}
pub fn test_find_min() {
    println!("{}", find_min!(1u32));
    println!("{}", find_min!(1u32 + 2, 2u32));
    println!("{}", find_min!(5u32, 2u32 * 3, 4u32));
}

